1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : common/classes/class.certificate.inc.php
5 : - Modulgruppe:
6 : - Beschreibung:
7 : - Version: 0.1, 17/06/08
8 : - Autor(en):
9 : +---------------------------------------------------------------------------+
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or any later version.
14 : +---------------------------------------------------------------------------+
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 : +--------------------------------------------------------------------------*/
23 : /**
24 : * In dieser Datei ist die Klasse Certificate implementiert.
25 : * Email-Zertifikate erstellen, downloaden, uploaden...
26 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
27 : * @version 0.1, 17/06/08
28 : * @package eStudy.
29 : *
30 : */
31 :
32 : /** relativer Pfad zum tmp Verseichnis */
33 : define("PATH_TO_TMP", PATH_TO_ROOT."tmp/");
34 :
35 : /**
36 : * BESCHREIBUNG
37 : * @package eStudy.
38 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
39 : * @version 0.1, 17/06/08
40 : */
41 : class Certificate{
42 :
43 : /**
44 : * Konstruktor
45 : * @access: public
46 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
47 : * @version 1.0, 30/07/08
48 : * @param integer $userID
49 : */
50 : public function Certificate($userID){
51 0 : global $db, $settings;
52 0 : $this->userData = $db->get_row("SELECT * FROM user WHERE ID = '".$userID."'");
53 0 : $this->userID = $userID;
54 0 : }
55 :
56 : /**
57 : * Erstellt ein Zertifikat
58 : * @access: private
59 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
60 : * @version 1.0, 30/07/08
61 : * @param string $pwPkey - Passwort für privaten Schlüssel
62 : */
63 : function createCert($pwPkey, $rootCA = false){
64 0 : global $db;
65 : // Angabe der Daten für den distinguished name, der in dem Zertifikat benutzt
66 : // wird. Sie müssen die Werte dieser Schlüssel so anpassen, dass diese ihrem
67 : // Namen und Firma entsprechen, oder um präziser zu sein, den Namen und die
68 : // Firma der Person/Seite angeben, für die Sie das Zertifikat erzeugen.
69 : // Für SSL Zertifikate entspricht der commonName gewöhnlich dem Domainnamen,
70 : // für den das Zertifikat benutzt werden soll, aber bei S/MIME Zertifikaten
71 : // entspricht der commonName dem Namen der Person, die das Zertifikat nutzen
72 : // möchte.
73 : $dn = array(
74 0 : "commonName" => $this->userData->Vorname." ".$this->userData->Nachname,
75 0 : "emailAddress" => $this->userData->Email
76 0 : );
77 0 : if($this->userData->countryID != 0){
78 : //CountryTabelle unbrauchbar
79 0 : }
80 :
81 0 : if($this->userData->location != null && $this->userData->location != "")
82 0 : $dn['localityName'] = $this->userData->location;
83 :
84 0 : if($this->userData->university != null && $this->userData->university != "")
85 0 : $dn['organizationName'] = $this->userData->university;
86 :
87 0 : if($this->userData->department != null && $this->userData->department != "")
88 0 : $dn['organizationalUnitName'] = $this->userData->department;
89 :
90 : // Erzeugen eines neuen privaten (und öffentlichen) Schlüsselpaars
91 0 : $privkey = openssl_pkey_new();
92 : // Erzeugen einer Zertifikatssignierungsanfrage
93 0 : $csr = openssl_csr_new($dn, $privkey);
94 :
95 : // Gewöhnlicherweise möchten Sie zu diesem Zeitpunkt ein selbstsigniertes
96 : // Zertifikat erzeugen, das Sie benutzten können, bis ihre CA ihre Anfrage
97 : // im positiven Sinne bearbeitet hat.
98 : // Erzeugen eines selbstsignierten Zertifikts, das für die Dauer von 365 Tagen
99 : // gültig ist.
100 :
101 0 : $sres = $db->get_row("SELECT * FROM secureemail");
102 0 : if(empty($sres->Certificate) || empty($sres->PrivatKey)){
103 0 : $cacert = null;
104 0 : $privkey_sign = $privkey;
105 0 : }else{
106 0 : $cacert = $sres->Certificate;
107 0 : $privkey_sign = $sres->PrivatKey;
108 : }
109 :
110 0 : $sscert = openssl_csr_sign($csr, $cacert, $privkey_sign, 365);
111 :
112 0 : openssl_pkcs12_export($sscert,$pfx,$privkey,$pwPkey);
113 0 : openssl_pkcs12_read($pfx,$data,$pwPkey);
114 :
115 0 : $query = "Update user SET certificate = '".Data::toMysql($data['cert'])."', privkey = '".Data::toMysql($data['pkey'])."' WHERE ID = '".Data::toMysql($this->userID)."'";
116 0 : $db->query($query);
117 0 : }
118 :
119 : /**
120 : * Stellt den Download des Zertifikats zur Verfügung
121 : * @access: private
122 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
123 : * @version 1.0, 30/07/08
124 : * @param string $pwPkey - Passwort für privaten Schlüssel
125 : *
126 : */
127 : function getPfx($pwPkey){
128 0 : $sscert = openssl_x509_read($this->userData->certificate);
129 0 : $privkey = openssl_pkey_get_private($this->userData->privkey,$pwPkey);
130 0 : openssl_pkcs12_export($sscert,$pfx,$privkey,$pwPkey);
131 :
132 : // Output-Buffering abschalten
133 0 : ob_end_clean();
134 : // HTTP Header Informationen senden, die ersten beiden sind wichtig für den IE
135 0 : header("Pragma: private");
136 0 : header("Cache-control: private, must-revalidate");
137 0 : header("Content-Type: text/plain");
138 0 : header("Content-Disposition: attachment; filename=SichereEmail-Zertifikat.pfx");
139 0 : header("Content-Transfer-Encoding: binary");
140 0 : header("Content-Length: ".strlen($pfx)."");
141 :
142 : //die datei senden
143 : //readfile("outlook.pfx");
144 0 : print($pfx);
145 0 : return "";
146 : }
147 :
148 : /**
149 : * Überprüft ob das angegebene Passwort zu dem Privaten Schlüssl gehört
150 : * @access: private
151 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
152 : * @version 1.0, 30/07/08
153 : * @param string $pwPkey - Passwort für privaten Schlüssel
154 : * @return im Erfolgsfall eine positive Schlüssel-Ressourcenkennung, FALSE im Fehlerfall
155 : */
156 : function checkPwPkey($pwPkey){
157 0 : return openssl_pkey_get_private($this->userData->privkey,$pwPkey);
158 : }
159 :
160 : /**
161 : * Gibt Informationen über das Zertifikat wieder
162 : * @access: private
163 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
164 : * @version 1.0, 30/07/08
165 : * @return im Erfolgsfall ein array mit Zertifikatsinformationen, FALSE im Fehlerfall
166 : */
167 : function getCertInfo(){
168 0 : if($this->userData->certificate != ""){
169 0 : $data = openssl_x509_parse($this->userData->certificate, true);
170 0 : if(!isset($data["subject"]["O"]))
171 0 : $data["subject"]["O"] = "";
172 0 : if(!isset($data["subject"]["OU"]))
173 0 : $data["subject"]["OU"] = "";
174 0 : if(!isset($data["subject"]["L"]))
175 0 : $data["subject"]["L"] = "";
176 0 : if(!isset($data["issuer"]["O"]))
177 0 : $data["issuer"]["O"] = "";
178 0 : if(!isset($data["issuer"]["OU"]))
179 0 : $data["issuer"]["OU"] = "";
180 0 : if(!isset($data["issuer"]["L"]))
181 0 : $data["issuer"]["L"] = "";
182 :
183 0 : foreach (array_keys($data["subject"]) as $key) {
184 0 : $data["subject"][$key] = utf8_decode($data["subject"][$key]);
185 0 : }
186 0 : foreach (array_keys($data["issuer"]) as $key) {
187 0 : $data["issuer"][$key] = utf8_decode($data["issuer"][$key]);
188 0 : }
189 :
190 0 : return $data;
191 : }else{
192 0 : return false;
193 : }
194 : }
195 :
196 : /**
197 : * Erstellt die verschlüsselte Emailnachricht
198 : * @access: private
199 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
200 : * @version 1.0, 30/07/08
201 : * @param array $data - Emailinformationen(Empfänger, Absender, Betreff)
202 : * @return im Erfolgsfall ein array mit den Mail-Teilen, FALSE im Fehlerfall
203 : */
204 : function makeEmailMessage($data){
205 0 : global $db;
206 0 : $msg = tempnam(PATH_TO_TMP,"");
207 0 : $enc = tempnam(PATH_TO_TMP,"");
208 0 : $signedmsg = tempnam(PATH_TO_TMP,"");
209 :
210 0 : $res = $db->get_row("SELECT certificate,privkey FROM user WHERE ID = '".$this->userID."'");
211 0 : $cert = openssl_x509_read($res->certificate);
212 0 : $key = openssl_pkey_get_public($cert);
213 :
214 0 : $props = array("To" => $data['to'],
215 0 : "From" => $data['from'],
216 0 : "Subject" => $data['subject']);
217 :
218 0 : $datei = fopen($msg,"w+");
219 0 : fwrite($datei, "\r\n".$data['message']);
220 0 : fclose($datei);
221 :
222 0 : $sres = $db->get_row("SELECT certificate, privkey FROM user WHERE ID=" . $this->userID);
223 :
224 0 : if(empty($sres->certificate) || empty($sres->privkey)){
225 0 : return false;
226 : }else{
227 0 : openssl_pkcs7_sign($msg, $signedmsg, $sres->certificate,$sres->privkey,array());
228 0 : openssl_pkcs7_encrypt($signedmsg, $enc, $cert, $props);
229 : }
230 :
231 0 : $maildata = file_get_contents($enc);
232 : // separate header and body, to use with mail function
233 : // unfortunate but required, else we have two sets of headers
234 : // and the email client doesn't decode the attachment
235 0 : $mailparts = explode("\n\n", $maildata, 2);
236 0 : unlink($enc);
237 0 : unlink($msg);
238 0 : unlink($signedmsg);
239 0 : return $mailparts;
240 : }
241 :
242 : /**
243 : * Importiert ein User-Zertifikat
244 : * @access: private
245 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
246 : * @version 1.0, 30/07/08
247 : * @param string $file - Pfad
248 : * @param string $name - Dateiname
249 : * @return im Erfolgsfall TRUE, FALSE im Fehlerfall
250 : */
251 : function importCert($file, $name){
252 0 : global $db;
253 0 : if(substr($name, -4) != ".pfx")
254 0 : return false;
255 0 : $cert = file_get_contents($file);
256 0 : openssl_pkcs12_read($cert,$data,$_POST['password']);
257 0 : if($data != null){
258 0 : $query = "Update user SET certificate = '".Data::toMysql($data['cert'])."', privkey = '".Data::toMysql($data['pkey'])."' WHERE ID = '".Data::toMysql($this->userID)."'";
259 0 : $db->query($query);
260 0 : return true;
261 : }else{
262 0 : return false;
263 : }
264 : }
265 :
266 : /**
267 : * Importiert das Root Zertifikat
268 : * @access: public
269 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
270 : * @version 1.0, 30/07/08
271 : * @param string $file - Pfad
272 : * @param string $name - Dateiname
273 : * @return im Erfolgsfall TRUE, FALSE im Fehlerfall
274 : */
275 : public function importRootCert($file, $name){
276 0 : global $db;
277 0 : if(substr($name, -4) != ".pfx")
278 0 : return false;
279 0 : $cert = file_get_contents($file);
280 0 : openssl_pkcs12_read($cert,$data,$_POST['password']);
281 0 : if($data != null){
282 0 : $query = "Update secureemail SET Certificate = '".Data::toMysql($data['cert'])."', PrivatKey = '".Data::toMysql($data['pkey'])."'";
283 0 : $db->query($query);
284 0 : return true;
285 : }else{
286 0 : return false;
287 : }
288 : }
289 :
290 : /**
291 : * Gibt die Root-Zertifikatsinformationen zurück
292 : * @access: public
293 : * @author Tobias Wolf <tobias.wolf@mni.fh-giessen.de>
294 : * @version 1.0, 30/07/08
295 : * @return im Erfolgsfall ein array mit Zertifikatsinformationen, FALSE im Fehlerfall
296 : */
297 : public function getRootCertInfo(){
298 0 : global $db;
299 0 : $res = $db->get_row("SELECT Certificate FROM secureemail");
300 0 : if($res->Certificate != ""){
301 0 : $data = openssl_x509_parse($res->Certificate, true);
302 0 : if(!isset($data["subject"]["O"]))
303 0 : $data["subject"]["O"] = "";
304 0 : if(!isset($data["subject"]["OU"]))
305 0 : $data["subject"]["OU"] = "";
306 0 : if(!isset($data["subject"]["L"]))
307 0 : $data["subject"]["L"] = "";
308 0 : if(!isset($data["issuer"]["O"]))
309 0 : $data["issuer"]["O"] = "";
310 0 : if(!isset($data["issuer"]["OU"]))
311 0 : $data["issuer"]["OU"] = "";
312 0 : if(!isset($data["issuer"]["L"]))
313 0 : $data["issuer"]["L"] = "";
314 0 : return $data;
315 : }else{
316 0 : return false;
317 : }
318 : }
319 :
320 : }
321 :
322 :
|